package com.intre.open.gwtjpa.main.client;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.Style.Orientation;
import com.extjs.gxt.ui.client.data.BaseListLoadConfig;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.ListLoadConfig;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.IconButtonEvent;
import com.extjs.gxt.ui.client.event.KeyListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.util.Util;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Html;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ToolButton;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.FormPanel.Method;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.RowData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.extjs.gxt.ui.client.widget.tips.ToolTipConfig;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.RootPanel;
import com.intre.open.gwtjpa.data.first.client.service.DataFirstService;
import com.intre.open.gwtjpa.data.first.client.service.DataFirstServiceAsync;
import com.intre.open.gwtjpa.data.first.domain.Person;
import com.intre.open.gwtjpa.data.second.client.service.DataSecondService;
import com.intre.open.gwtjpa.data.second.client.service.DataSecondServiceAsync;
import com.intre.open.gwtjpa.resources.client.Resources;

public class Explorer implements EntryPoint {
	
	private Viewport viewport;
	private ListLoader<ListLoadResult<ModelData>> loaderFirst;
	private ListStore<BeanModel> storeFirst;
	private Grid<BeanModel> gridFirst;
	private TextField<String> searchTextField;
	private DataFirstServiceAsync firstService;
	private DataSecondServiceAsync secondService;

	public static void loadingMessage(String message) {

		try {
			RootPanel.get("loading-msg").getElement().setInnerHTML(message);
		} catch (Exception e) {

		}
	}

	public void onModuleLoad() {

		try {
			viewport = new Viewport();
			viewport.setLayout(new BorderLayout());
			firstService = DataFirstService.Util.getInstance();
			secondService = DataSecondService.Util.getInstance();
			RootPanel.get().add(viewport);
			_init();
		} catch (Exception e) {
			_error(e);
		}
	}

	private void _init() {

		_createSearch();
		_createGrid();

	}

	private void _createSearch() {

		final FormPanel panel = new FormPanel();
		panel.setIcon(Resources.ICONS.table());
		panel.setHeading("Full Text Search");
		panel.setFrame(true);
		panel.setMethod(Method.POST);
		panel.setSize("100%", "75px");
		panel.setLayout(new RowLayout(Orientation.HORIZONTAL));
		panel.setCollapsible(true);

		ToolTipConfig tc = new ToolTipConfig();
		tc.setTitle("First");
		tc.setShowDelay(1);
		tc.setText("First");

		ToolButton tbHelp = new ToolButton("x-tool-help", new SelectionListener<IconButtonEvent>() {
			@Override
			public void componentSelected(IconButtonEvent ce) {
				MessageBox.info("", "", null);
			}
		});
		tbHelp.setToolTip(tc);
		panel.getHeader().addTool(tbHelp);

		searchTextField = new TextField<String>();
		searchTextField.setFieldLabel("Name");
		searchTextField.setWidth(400);
		searchTextField.setFireChangeEventOnSetValue(true);
		searchTextField.setValue("");
		searchTextField.focus();

		searchTextField.addKeyListener(new KeyListener() {
			@Override
			public void componentKeyPress(ComponentEvent event) {
				int code = event.getKeyCode();
				if (code == Resources.KEYBOARD_CODE_ENTER) {
					loaderFirst.load();
				}
				super.componentKeyPress(event);
			}
		});

		panel.add(searchTextField);
		panel.add(new Html("&nbsp"));

		Button btn = new Button("Search");
		btn.addSelectionListener(new SelectionListener<ButtonEvent>() {
			@Override
			public void componentSelected(ButtonEvent ce) {
				if (!panel.isValid()) {
					return;
				}
				loaderFirst.load();
			}
		});
		btn.setIcon(Resources.ICONS.table());
		panel.add(btn);

		viewport.add(panel, new RowData(1, -1, new Margins(5)));
	}

	public void _createGrid() {

		// proxy and reader
		RpcProxy<List<Person>> proxy = new RpcProxy<List<Person>>() {
			@Override
			public void load(Object loadConfig, final AsyncCallback<List<Person>> callback) {

				ListLoadConfig cfg = loadConfig != null && loadConfig instanceof ListLoadConfig ? (ListLoadConfig) loadConfig : null;
				boolean loadAll = cfg.get("loadAll") == null ? false : (Boolean) cfg.get("loadAll");

				// Query using Hibernate Search
				if (!loadAll && !Util.isEmptyString(searchTextField.getValue())) {
//					surveyService.searchObjects(FlatCampaign.class.getName(), searchTextField.getValue(),
//							new AsyncCallback<List<IPolluxBeanModelTag>>() {
//								@Override
//								public void onSuccess(List<IPolluxBeanModelTag> result) {
//									if (result == null)
//										result = new ArrayList<IPolluxBeanModelTag>(0);
//									callback.onSuccess(result);
//								}
//
//								@Override
//								public void onFailure(Throwable caught) {
//									CustomMessageBox.error(Resources.MESSAGES.ERROR(), Resources.MESSAGES.msgErrorGeneric(caught.getMessage()), null);
//									callback.onFailure(caught);
//								}
//							});
					// Query using HQL
				} else {
					firstService.getAll(new AsyncCallback<List<Person>>() {
						@Override
						public void onSuccess(List<Person> result) {
							if (result == null)
								result = new ArrayList<Person>(0);
							callback.onSuccess(result);
						}

						@Override
						public void onFailure(Throwable caught) {
							callback.onFailure(caught);
						}
					});
				}
			}
		};
		BeanModelReader reader = new BeanModelReader();

		// loader and store
		loaderFirst = new BaseListLoader<ListLoadResult<ModelData>>(proxy, reader);
		storeFirst = new ListStore<BeanModel>(loaderFirst);
		ListLoadConfig config = new BaseListLoadConfig();
		config.set("loadAll", true);
		loaderFirst.load(config);

		// column model
		List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
		columns.add(new ColumnConfig("id", 50));
		columns.add(new ColumnConfig("name", 100));
		columns.add(new ColumnConfig("surname", 100));
		ColumnModel cm = new ColumnModel(columns);
		gridFirst = new Grid<BeanModel>(storeFirst, cm);
		gridFirst.setStripeRows(true);
		gridFirst.setLoadMask(true);

		ContentPanel panel = new ContentPanel();
		panel.setIcon(Resources.ICONS.table());
		panel.setLayout(new FitLayout());
		panel.add(gridFirst);

		// toolbar
		//panel.setTopComponent(_createToolbar());

		viewport.add(panel, new RowData(1, 1, new Margins(0, 5, 5, 5)));
	}

	private void _error(Throwable e) {

		RootPanel.get("loading").setVisible(false);
		MessageBox.alert("Failed to start the GWT JPA Use Case Application",
				"Please verify that your browser/platform satisfy the minimal requirements. Exception[" + e.getMessage() + "]", null);
		e.printStackTrace();
	}

}
